package com.szwistar.iot;

import com.j256.ormlite.field.DataType;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * 针对对象属性字段的注解类
 * <p>此注解类的目的是对对象属性进行描述，可用于自动生成UI、智能规则事件过滤条件编辑等场景
 * @author 张勇 2018-3-21
 */
@Documented
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface CoAttrDef {
    /**
     * 中文名称
     */
    String title();

    /**
     * 是一个 JS 的表达式字符串，返回一个布尔值，用于指示此字段在什么条件下有效
     * <p>此 JS 表达式在进行 eval() 前，会定义以下变量，可在表达式中引用：
     * <li>me 表示此字段所在的对象本身；可通过它引用其它字段的值，实现条件判断，从而实现字段间的联动
     * <li>obj 表示一个对象，具体含义由用户自己定义
     * <p>默认值为 "true"，表示此字段有效
     */
    String enableOn() default "true";

    /**
     * 是否必需(不能为空)
     */
    boolean required() default false;

    /**
     * 所在的属性分组名
     * <p>组名可以用来对对象的多个字段进行分组显示/编辑，属于同一分组的字段，应放在一起显示/编辑
     * <p>组名支持多级分组，中间用 "/" 分开，如: "WiFi参数/AP", "WiFi参数/STA/固定IP" 等
     * <p>组名默认为空，表示默认分组
     * <p>组名用于 UI 界面自动生成时，各个分组中的字段如何组织和显示，由前端自己定义。如：1级分组用 TAB 页分开；2级分组用抽屉分开；...
     */
    String group() default "";

    /**
     * 取值范围类型
     * <p>常用的取值范围类型如下：
     * <li>boolean
     * <li>number
     * <li>string
     * <li>stringArray 字符串列表，格式如：["按钮1","按钮2","按钮3"]
     * <li>list 列表，格式如： [{"中国":0},{"美国":1}]
     * <li>ipv4 IPv4 地址
     * <li>ipv4Info 3 个 IPv4 地址: IP/MASK/GATEWAY
     * <li>switch 开关通道
     * <li>switchPair 开关通道配对信息
     * <li>button 面板按钮
     * <li>buttonPair 面板按钮配对信息
     * <li>innerSlots 内置设备位置信息
     */
    String rangeType() default "";

    /**
     * 取值范围定义(JSON格式)，可做为字段编辑时的取值范围
     * <p>不同的 rangeType 对应的 range 的定义也不同
     * <li>rangeType="number"时，range="[0,3]"，表示数字取值范围为 0~3
     * <li>rangeType="string"时，range="[6,12]"，表示字符串长度最小为6字符，最大为12字符
     */
    String range() default "";

    /**
     * 数值的单位，可被做为字段值的显示单位，如: % ℃ ℉ ¥ $
     */
    String unit() default "";

    /**
     * 描述
     */
    String description() default "";

    /**
     * 对应的上限字段名
     */
    String upperLimitFieldName() default "";

    /**
     * 对应的下限字段属性ID
     */
    String lowerLimitFieldName() default "";

    /**
     * 对应的二进制字段类型(用于自动生成 Java/C 等语言代码)
     */
    String binType() default "int";

    /**
     * 可读
     */
    boolean readable() default true;

    /**
     * 可写
     */
    boolean writable() default true;

    /**
     * 变化时触发事件
     */
    boolean triggerOnChange() default false;

    /**
     * 越上限时触发事件
     */
    boolean triggerOnUpperLimit() default false;

    /**
     * 越下限时触发事件
     */
    boolean triggerOnLowerLimit() default false;

    /**
     * (在设备上)是否需要持久化(如果需要持久化，则一般意味着需要保存为 Flash 参数)
     */
    boolean persistOnDevice() default false;

    /**
     * (在服务器/网关上)是否需要持久化(如果需要持久化，则一般意味着需要保存到数据库)
     */
    boolean persistOnServer() default false;

    /**
     * 设备出厂默认参数(JSON 字符串，需要根据实际类型转化)
     */
    String factoryDefault() default "";

    /**
     * 保存到数据库时的字段名
     */
    String dbFieldName() default "";

    /**
     * 保存到数据库时的字段类型
     */
	DataType dbDataType() default DataType.UNKNOWN;

	/**
	 * 保存到数据库时的字段长度
	 */
	int dbWidth() default 0;
}
